package bandwidthcontroller;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.FileHandler;
import java.util.logging.SimpleFormatter;
import java.util.Timer;
import static java.lang.System.out;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;

/**
 *
 * @author ppdbuilder
 */
 

public class BandwidthMonitor implements Runnable{
        
        private Double previousTx;
        private Double currentTx;
        private Double previousRx;
        private Double currentRx;
        private Double previousTime;
        private Double currentTime;
        private String iFace;
        public static String bandWidth;
        Logger logger = Logger.getLogger("Bandwidth log");
        FileHandler fh;
        static final String LOGFILE = "/home/flixnet/bandwidthlog.log";
        File bandwidthmonitorlog;
        BufferedWriter logWriter;
        
    
        
        public BandwidthMonitor(String iface){
            try{
                File curDir = new File(".");
                this.iFace = iface;
                String logpath = LOGFILE;
                this.bandwidthmonitorlog = new File(logpath);
                
                if(!this.bandwidthmonitorlog.exists()){
                   this.bandwidthmonitorlog.createNewFile();
                  }
                
                this.logWriter = new BufferedWriter(new FileWriter(this.bandwidthmonitorlog,true));
                
                }
                catch(IOException ioe){
                   ioe.printStackTrace();
                }
            
            
        }
        
       
        
        public void run(){
        while(true){
            try {

                String[] previousstatcounters = this.getStats();


                Thread.sleep(5000);
                String[] currentstatcounters = this.getStats();
                String bandwidth = this.getBandwidth(previousstatcounters, currentstatcounters)+"kbit/s";
                System.out.println("BANDWIDTH: " + bandwidth);                
                this.logBandwidth(bandWidth);
                setBandwidth(bandwidth);
                
                System.out.println("BANDWIDTH: " + bandwidth);                
                this.logBandwidth(bandWidth);
                
                
            } catch (InterruptedException ex) {
                Logger.getLogger(BandwidthMonitor.class.getName()).log(Level.SEVERE, null, ex);
            }
            
            
            
        }
        }
        
        public void logBandwidth(String bandwidth){
        try {
         
            Calendar c = new GregorianCalendar();
            String tstamp = c.get(Calendar.HOUR)+":"+c.get(Calendar.MINUTE)+":"+c.get(Calendar.SECOND)+"\t\t";
            this.logWriter.write(c.get(Calendar.HOUR)+":"+c.get(Calendar.MINUTE)+":"+c.get(Calendar.SECOND)+"\t\t");
            this.logWriter.write(bandwidth+"\n");
            bandwidth = tstamp + bandwidth;
            this.logWriter.flush();
            
        } catch (IOException ex) {
            Logger.getLogger(BandwidthMonitor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(BandwidthMonitor.class.getName()).log(Level.SEVERE, null, ex);
        }
            
        }
        
        synchronized
        public void setBandwidth(String bandwidth){
            
            this.bandWidth = bandwidth;
        }
        
        synchronized
        public String getCurrentBandwidth(){
        try {
            Calendar c = new GregorianCalendar();
            String tstamp = c.get(Calendar.HOUR)+":"+c.get(Calendar.MINUTE)+":"+c.get(Calendar.SECOND)+"\t\t";
            this.logWriter.write(c.get(Calendar.HOUR)+":"+c.get(Calendar.MINUTE)+":"+c.get(Calendar.SECOND)+"\t\t");
            this.logWriter.write(bandWidth+"\n");
            bandWidth = tstamp + bandWidth;
            return this.bandWidth;
        } catch (IOException ex) {
            Logger.getLogger(BandwidthMonitor.class.getName()).log(Level.SEVERE, null, ex);
            return null;

        }
            
        }
        public Double getBandwidth(String[] previousCounters, String[] currentCounters){
            
            previousTime = Double.parseDouble(previousCounters[0]);
            previousRx = Double.parseDouble(previousCounters[1]);
            previousTx = Double.parseDouble(previousCounters[2]);
            
            currentTime = Double.parseDouble(currentCounters[0]);
            currentRx = Double.parseDouble(currentCounters[1]);
            currentTx = Double.parseDouble(currentCounters[2]);
            
            Double bandwidth = Double.valueOf(0);
            Double elapsedtime = (currentTime - previousTime)/1000;
            out.println("ELAPSEDTIME" + elapsedtime);
            bandwidth =(currentRx - previousRx);
            out.println("diff:" + bandwidth);
            bandwidth = (bandwidth  * 8)/1024;
            out.println("KB:"+bandwidth);
            bandwidth = bandwidth / elapsedtime;
            out.println("BW:"+bandwidth);
            
            return roundTwoDecimalPlaces(bandwidth);
            
        }
        
        private Double roundTwoDecimalPlaces(Double bandwidth){
            
            DecimalFormat twoplaces = new DecimalFormat("#.##");
            return Double.valueOf(twoplaces.format(bandwidth));
            
        }
        
       
        public String[] getStats(){
            String interest = "";
            String[] stats = new String[3];
            Long timestamp;
         
                try {
                    Runtime runtime = Runtime.getRuntime();
                    Process process = runtime.exec("cat /proc/net/dev");
                    process.waitFor();
                    
                    timestamp = System.currentTimeMillis();
                    System.out.println(timestamp);
                    stats[0] = timestamp.toString();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                    String line = reader.readLine();
                    
                    while(true){
//                        out.println(line);
                        line = reader.readLine();
                        if(line == null)
                            break;
                        if(line.contains(this.iFace)){
                            interest = line;
                        }
                        
                            
                    }
                    out.println("INTEREST:"+interest);
                    process.destroy();
                    
                } catch (InterruptedException ex) {
                    Logger.getLogger(BandwidthMonitor.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(BandwidthMonitor.class.getName()).log(Level.SEVERE, null, ex);
                }
                
                String[] result = interest.split(":");
                for(String temp: result)
                    out.println(temp);
                if(result.length > 1){
                    Scanner s = new Scanner(result[1]);
                    int col = 0;

                    while(s.hasNext()){ 
                        String temp = s.next();
                        System.out.println(temp);
                        if(col==0)
                            stats[1] = temp;
                        else if(col==8)
                            stats[2] = temp;
                        col++;
                    }
                }
                else{
                    stats[1]="0";
                    stats[2]="0";
                }
                    
                
                 return stats;
            
            } 
        
        
     
           
        
        
}